package ar.com.larreta.colegio.entidades;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

import ar.com.larreta.comunes.Propiedades;
import ar.com.larreta.entidades.Entidad;
import ar.com.larreta.procesos.AdministradorDeProcesos;
import ar.com.larreta.utilidades.GeneradorClavesUnicas;
import ar.com.larreta.utilidades.NumeroLetra;
import ar.com.larreta.utilidades.UtilidadesFechas;
import ar.com.larreta.utilidades.UtilidadesNumeros;

@Entity
@Table(name = "pago")
// Borrado logico
@SQLDelete (sql="UPDATE Pago SET fechaEliminacion=CURRENT_TIMESTAMP WHERE ID=?")
// Solamente trae los que no fueron borrados logicamente
@Where(clause="fechaEliminacion IS NULL")
public class Pago extends Entidad implements Comparable<Pago>{

	public static final String FORMATO_FECHA = "formato.fecha";
	public static final String FORMATO_NUMERICO = "formato.numerico";
	public static final String SIMBOLO_MONETARIO = "simbolo.monetario";
	
	private Long id;
	private Responsable responsable;
	private Set<UnidadDePago> unidades;
	
	@Id 
	public Long getId() {
		if(id==null){
			GeneradorClavesUnicas clavesUnicas = new GeneradorClavesUnicas();
			id = clavesUnicas.getLastTime();
		}
		return id;
	}
	
	public void setId(Long id) {
		this.id = id;
	}
	
	@Transient
	public String getIdConFormato(){
		return UtilidadesNumeros.transformarConCerosAIzquierda(id, 15);
	}

	@Transient
	public String getNombreCompletoResponsable(){
		if (responsable==null) {
			return StringUtils.EMPTY;
		}
		return responsable.getNombreCompleto();
	}
	
	@ManyToOne (fetch=FetchType.LAZY)
	@JoinColumn (name="idResponsable")
	public Responsable getResponsable() {
		return responsable;
	}

	public void setResponsable(Responsable responsable) {
		this.responsable = responsable;
	}

	@Transient
	public String getFechaCreacionConFormato(){
		Propiedades propiedadesDeConfiguracionDeLaAplicacion = AdministradorDeProcesos.getInstancia(null).getPropiedades();
		return UtilidadesFechas.transformarFechaEnTexto(getFechaCreacion(), propiedadesDeConfiguracionDeLaAplicacion.getProperty(FORMATO_FECHA));
	}
	
	@OneToMany (mappedBy="pago", fetch=FetchType.LAZY, cascade=CascadeType.ALL)
	// Solamente trae los que no fueron borrados logicamente
	@Where(clause="fechaEliminacion IS NULL")
	public Set<UnidadDePago> getUnidades() {
		return unidades;
	}

	public void setUnidades(Set<UnidadDePago> unidades) {
		if (unidades!=null){
			Date fechaActual = new Date();
			Iterator<UnidadDePago> iterator = unidades.iterator();
			while (iterator.hasNext()) {
				UnidadDePago unidad = (UnidadDePago) iterator.next();
				unidad.setPago(this);
				unidad.setFechaCreacion(fechaActual);
			}
		}
		this.unidades = unidades;
	}
	
	@Transient
	public Alumno getAlumno() {
		Alumno alumno = null;
		if ((unidades!=null) && (unidades.size()==1)){
			UnidadDePago unidadDePago = unidades.iterator().next();
			alumno = unidadDePago.getAlumno();
		}
		return alumno;
	}
	public void setAlumno(Alumno alumno) {
		UnidadDePago unidadDePago = getUnidad();
		unidadDePago.setAlumno(alumno);
		unidades.add(unidadDePago);
	}

	@Transient
	private UnidadDePago getUnidad() {
		if (unidades==null){
			unidades = new HashSet<UnidadDePago>();
		}
		UnidadDePago unidadDePago = null;
		if (unidades.size()<1){
			unidadDePago = new UnidadDePago();
		} else {
			unidadDePago = unidades.iterator().next();
		}
		return unidadDePago;
	}
	
	@Transient
	public Producto getProducto() {
		Producto producto = null;
		Set<UnidadDePago> unidadesDePago = getUnidades();
		if ((unidadesDePago!=null) && (unidadesDePago.size()==1)){
			UnidadDePago unidadDePago = unidadesDePago.iterator().next();
			producto = unidadDePago.getProducto();
		}
		return producto;
	}
	public void setProducto(Producto producto) {
		UnidadDePago unidadDePago = getUnidad();
		unidadDePago.setProducto(producto);
		unidades.add(unidadDePago);
	}	
	
	@Transient
	public Double getValor() {
		Double valor = null;
		if ((unidades!=null) && (unidades.size()==1)){
			UnidadDePago unidadDePago = unidades.iterator().next();
			valor = unidadDePago.getValor();
		}
		return valor;
	}
	
	public void setValor(Double valor) {
	}
	
	@Transient
	public String getValorEnLetras(){
		Double valor = getValor();
		if (valor==null){
			return StringUtils.EMPTY;
		}
		NumeroLetra numeroLetra = new NumeroLetra();
		return numeroLetra.convertirLetras(valor);
	}
	
	@Transient
	public String getValorConFormato(){
		if (getValor()==null){
			return StringUtils.EMPTY;
		}
		Propiedades propiedadesDeConfiguracionDeLaAplicacion = AdministradorDeProcesos.getInstancia(null).getPropiedades();
		return propiedadesDeConfiguracionDeLaAplicacion.getProperty(SIMBOLO_MONETARIO) + 
				UtilidadesNumeros.transformarNumeroATexto(getValor(), propiedadesDeConfiguracionDeLaAplicacion.getProperty(FORMATO_NUMERICO));
	}
	
	
	public int compareTo(Pago pago) {
		return this.getFechaCreacion().compareTo(pago.getFechaCreacion()) * (-1);
	}
	
	@Transient
	public String getReciboDetallesTitulo(){
		StringBuffer txt = new StringBuffer();
		if (getProducto()!=null){
			if ((getProducto() instanceof Obligacion) 
					&& (((Obligacion)getProducto()).getDetalles()!=null)
					&& (((Obligacion)getProducto()).getDetalles().size()>0)
				) {
				txt.append("Detalles");
			} else {
				txt.append("Valor total por ");
				txt.append(getProducto().getNombre());
				txt.append("\t\t\t");
				txt.append(getProducto().getValor());
			}
		}
		return txt.toString();
	}
	
}
